package com.yzh.openai.domain.openai.service;

import com.yzh.openai.domain.openai.model.aggregates.ChatProcessAggregate;
import com.yzh.openai.domain.openai.model.entity.RuleLogicEntity;
import com.yzh.openai.domain.openai.model.entity.UserAccountEntity;
import com.yzh.openai.domain.openai.model.valobj.LogicCheckTypeVO;
import com.yzh.openai.domain.openai.repository.IOpenAiRepository;
import com.yzh.openai.domain.openai.service.channel.abstractFactory.ModelGroupFactory;
import com.yzh.openai.domain.openai.service.rule.factory.DefaultLogicFactory;
import com.yzh.openai.types.common.Constants;
import com.yzh.openai.types.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

@Slf4j
public abstract class AbstractChatService implements IChatService {
    @Resource
    protected IOpenAiRepository openAiRepository;
    @Resource
    protected ModelGroupFactory modelGroupFactory;

    @Override
    public ResponseBodyEmitter completions(ChatProcessAggregate chatProcessAggregate) throws IOException, ExecutionException {
        //1.请求应答
        ResponseBodyEmitter emitter = new ResponseBodyEmitter(3 * 60 * 1000L);
        emitter.onCompletion(() -> {
            log.info("流式问答请求完成，使用模型：{}", chatProcessAggregate.getModel());
        });
        emitter.onError(throwable -> log.error("流式问答请求异常，使用模型：{}", chatProcessAggregate.getModel(), throwable));

        //2.账户获取
        UserAccountEntity userAccountEntity = openAiRepository.queryUserAccount(chatProcessAggregate.getOpenid());
        
        //3.规则规律
        RuleLogicEntity<ChatProcessAggregate> ruleLogicEntity = doCheckLogic(chatProcessAggregate, userAccountEntity,
                DefaultLogicFactory.LogicModel.SENSITIVE_WORD.getCode(),
                null != userAccountEntity ? DefaultLogicFactory.LogicModel.ACCOUNT_STATUS.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode(),
                null != userAccountEntity ? DefaultLogicFactory.LogicModel.MODEL_TYPE.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode(),
                null != userAccountEntity ? DefaultLogicFactory.LogicModel.USER_QUOTA.getCode() : DefaultLogicFactory.LogicModel.NULL.getCode());

        if (!LogicCheckTypeVO.SUCCESS.equals(ruleLogicEntity.getType())) {
            emitter.send(ruleLogicEntity.getInfo());
            emitter.complete();
            return emitter;
        }

        //4.应答处理
        try {
            modelGroupFactory.getModelGroup(chatProcessAggregate.getModel().getCode()).doMessageResponse(ruleLogicEntity.getData(), emitter);
        } catch (Exception e) {
            throw new BusinessException(Constants.ResponseCode.UN_ERROR, Constants.ResponseCode.UN_ERROR.getInfo());
        }
        //5.返回结果
        return emitter;
    }

    protected abstract RuleLogicEntity<ChatProcessAggregate> doCheckLogic(ChatProcessAggregate chatProcess, UserAccountEntity data, String... logics) throws ExecutionException;

}
